/**
 * 
 */
(function(factory){
    if (typeof define === "function" && define.amd) {
        define(['Vue'], factory);
    } else {
        factory(Vue);
    }
})(function(Vue){
    var checkWhenChange = true;

    notEmpty = function(el, rules) {
        return el.value.trim() ? true : false;
    }

    var onezv = {};
    onezv.install = function(Vue, options) {
        Vue.directive("onezv", {
            inserted: function(el, binding, vnode){
                if (binding.value){
                    el.focus();
                } else {
                    el.blur();
                }
            },
            bind: function(el, binding, vnode){
                var vm  = vnode.context;
                var tag = el.getAttribute("tag") || el.getAttribute("name");
                if (checkWhenChange) {
                    function checkSingle() {
                        if (!notEmpty(el, null)) {
                            console.log("is in ....");
                        }
                    }
                    el.addEventListener('change', checkSingle);
                    el.addEventListener('blur', checkSingle);
                }
            }
        });
    }

    Vue.use(onezv);
});


// // 本js未使用只作为一个思路
// // 任何表单验证模块都是由 配置——校验——报错——取值 这几部分构成的。
// //     配置： 配置规则 和配置报错，以及优先级
// //     校验： 有在 change 事件校验， 在点击提交按钮的时候校验， 当然也有在input事件取值的
// //     报错： 报错方式一般要分，报错的文字有模板，也有自定义的
// //     取值： 将通过验证的数据返还给开发者调用
// // 下面是要求
// //     集中式的管理 校验规则 和 报错模板。
// //     报错时机可选
// //     校验正确后的数据，已经打包成对象，可以直接用
// //     允许各个页面对规则进行覆盖，对报错信息进行自定义修改，以及允许ajax获取数据后，再对规则进行补充
// //     按顺序来校验，在第一个报错的框弹出错误

// var Vue
// var checkWhenChange = true  //每个输入框需要离焦即校验

// // 给一个dom添加class
// function addClass(dom, className) {
//     var hasClass = !!dom.className.match(new RegExp('(\\s|^)' + _class + '(\\s|$)'))
//     if (!hasClass) {
//         dom.className += ' ' + _class
//     }
// }

// //常用正则表
// var regList = {
//     ImgCode: /^[0-9a-zA-Z]{4}$/,
//     SmsCode: /^\d{4}$/,
//     MailCode: /^\d{4}$/,
//     UserName: /^[\w|\d]{4,16}$/,
//     Password: /^[\w!@#$%^&*.]{6,16}$/,
//     Mobile: /^1[3|4|5|7|8]\d{9}$/,
//     RealName: /^[\u4e00-\u9fa5|·]{2,16}$|^[a-zA-Z|\s]{2,20}$/,
//     BankNum: /^\d{10,19}$/,
//     Money: /^([1-9]\d*|[0-9]\d*\.\d{1,2}|0)$/,
//     Answer: /^\S+$/,
//     Mail: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/
// }

// assert = function (condition, msg) {
//     if (!condition) {
//         console.error("[wit-va]:" + msg);
//     }
// }

// Rule = function (type, val, msg) {
//     this.type = type;
//     this.val = val;
//     this.msg = msg;
// }

// WvForm = function (el, finalRules, modifiers) {
//     this.ruleOrder = [];
//     this.rules = {};
//     this.dom = el;
//     this.value = el.value; // 值的副本
//     this.validated = false;    // 是否被验证过
//     this.tag = el.getAttribute('tag'); // 提示的字段名
//     this.correctMsg = '';
//     this.modifiers = modifiers; // 一些特殊的配置
//     this.noCheck = false;     // 为 true 则不需要校验

//     this.ruleOrder = finalRules.map(item => {
//         this.rules[item.type] = item;
//         return item.type;
//     });
// }

// mergeRule = function (...rules) {
//     var result = [];
//     var combineArr = Array.prototype.concat.apply([], rules);
//     var hash = {};
//     combineArr.forEach((rule) => {
//         if (hash[rule.type] === undefined) {
//             result.push(rule);
//             hash[rule.type] = result.length - 1;
//         } else {
//             index = hash[rule.type];
//             Object.assign(rule[index], rule);
//         }
//     });
//     return result;
// }

// WvResult = function (type, value, isPass, errMsg) {
//     this.type = type;
//     this.value = value;
//     this.isPass = isPass;
//     this.errMsg = errMsg;
// }

// DisplayResult = function (isPass, msg) {
//     this.isPass = isPass;
//     this.msg = msg;
// }

// // 单个规则或单个表单的校验
// validate = function (field, type) {
//     assert(field, "未输入要验证的字段.");
//     var wvForm = this.forms[field];
//     var { ruleOrder, rules } = wvForm;

//     if (type == undefined) {
//         return this.checkForm(wvForm);
//     } else {
//         var rule = rules[type];
//         return this.checkRule(wvForm, rule);
//     }
// }

// errorMsg = function (wvForm, type, value) {
//     var tag = wvForm.tag;
//     var msg = {
//         NonEmpty: '$[tag]不能为空.',
//         reg: '$[tag]格式错误.',
//         limit: '$[tag]长度必须在${value[0]}与${value[1]}之间.',
//         equal: '两次$[tag]不相同.',
//         unique: '$[tag]不能相同.',
//     }
//     return msg[type];
// }

// checkEmpty = function (rule, control, va) {
//     return control.value.trim() ? true : false;
// }

// checkRegexp = function (rVal, control, va) {
//     return rVal.test(control.value) ? true : false;
// }

// checkLimit = function (rVal, control, va) {
//     var val = control.value;
//     return ((+val >= rVal[0]) && (+val <= rVal[1]));
// }

// checkEqual = function (rVal, control, va) {
//     var target = va.forms[rVal];
//     return target.value === control.value ? true : false;
// }

// checkLength = function (rVal, control, va) {
//     var length = control.value.length;
//     return ((+length >= rVal[0]) && (+length <= rVal[1]));
// }

// checkUnique = function (rVal, control, va) {
//     var uniqueGroup = va.uniqueGroup[rVal];
//     var values = uniqueGroup.map(field => va.forms[field].value);
//     var uniqueValues = values.filter((item, index, arr) => arr.indexOf(item) === index);
//     return values.length === uniqueValues.length;
// }

// // 检验单个规则
// checkRule = function (control, rule) {
//     var forms = this.forms;
//     var { type, val, msg } = rule;
//     error = error || errorMsg(control, type, val);
//     var checkers = {
//         NonEmpty: checkEmpty,
//         regexp: checkRegexp,
//         limit: checkLimit,
//         equal: checkEqual,
//         length: checkLength,
//         unique: checkUnique
//     }
//     var checker = checkers[type];
//     var isPass = checker(val, control, this);
//     var result = new WvResult(type, val, isPass, isPass ? null : error);
//     return result
// }

// // 检验单个表单
// checkForm = function (wvForm) {
//     var results = wvForm.ruleOrder.map(type => {
//         var rule = wvForm.rules[type]
//         return this.checkRule(wvForm, rule);
//     });

//     var errInx = null;
//     for (var i = 0; i < results.length; i++) {
//         if (results[i].isPass === false) {
//             errInx = i;
//             break;
//         }
//     }

//     return new DisplayResult((errInx === null), (errInx === null ? wvForm.correctMsg : results[errInx].errMsg));
// }

// // 刷新 wvForm 中的值
// refreshValue = function (field, newVal) {
//     this.forms[field].value = newVal + '';
// }
// refreshAllValue = function () {
//     this.fieldOrder.forEach(field => {
//         var wvForm = this.forms[field];
//         wvForm.value = wvForm.dom.value;
//     })
// }

// checkAll = function () {
//     var firstErr = null;
//     this.fieldOrder.forEach(field => {
//         var wvForm = this.forms[field];
//         var canNull = wvForm.ruleOrder.every(type => type !== 'NonEmpty'); // 输入框可以为空
//         var noCheckEmpty = (wvForm.value === '' && canNull); // 该输入框可以为空，且输入为空
//         if (wvForm.noCheck === false && noCheckEmpty === false) {
//             var result = this.setVmResult(field);
//             if (firstErr === null && result.isPass === false) {
//                 firstErr = result.message;
//             }
//         }
//     })
//     return firstErr;
// }

// // 验证单个字段，返回值，并弹出报错
// setVmResult = function (field) {
//     var result = this.validate(field); // 本输入框结果
//     this.vmResult[field] = result; // 将报错弹出
//     this.forms[field].validated = true; // 校验过了
//     return result;
// }

// // 返回各个表单的值对象
// function getValue() {
//     var dataSet = {}
//     for (var field in this.forms) {
//         dataSet[field] = this.forms[field].value
//     }
//     return dataSet
// }

// //添加一个规则
// function addRule(field, index, Rule) {
//     var wvForm = this.forms[field]
//     wvForm.ruleOrder.splice(index, 0, Rule.ruleType)
//     wvForm.rules[Rule.ruleType] = Rule
// }

// // 设置不校验的表单
// function setNoCheck(field, bool) {
//     this.forms[field].noCheck = bool
// }

// function createVa(vm, field) {
//     var va = {
//         vmResult: vm.va,
//         fieldOrder: [],
//         forms: {},
//         group: {
//             base: [],
//         },
//         equalGroup: {},                  //必须相等的字段
//         uniqueGroup: {},                 //必须不同的字段
//         Rule: Rule,                      //Rule构造器
//         WvForm: WvForm,                  //wvForm构造器
//         validate: validate,             //暴露的校验函数
//         setVmResult: setVmResult,       //校验并报错
//         checkRule: checkRule,           //内部的校验单条规则的函数
//         checkForm: checkForm,           //内部的校验单个表单的函数
//         refreshValue: refreshValue,     //更新某个表单的值
//         checkAll: checkAll,             //检查所有的函数
//         getValue: getValue,             //获取所有表单的当前值，得到一个对象
//         setNoCheck: setNoCheck,          //设置为不校验
//         addRule: addRule,                //给一个表单添加一个规则
//         refreshAllValue: refreshAllValue //更新所有表单的值
//         // resetAll: resetAll
//     }

//     if (vm.$va) {
//         return vm.$va
//     } else {
//         vm.$va = va
//         return va
//     }
// }

// //v-wv:Password.canNull = "[{reg:/^\d{4}$/}]"
// //arg = Password,  modifiers.canNull = true, value为后面相关的
// //arg用来存字段名， modifiers用来存特殊配置， value为规则， tag是中文提示名， group 为分组
// var wv = {}
// wv.install = function (_Vue, options) {
//     _Vue.directive('wv', {
//         bind: function (el, binding, vnode) {
//             var vm = vnode.context                         //当前的vue实例
//             var field = binding.arg === 'EXTEND' ? el.getAttribute('name') : binding.arg // 当arg为EXTEND，从name属性获得值
//             var option = binding.modifiers                    //特殊配置（允许非空，编辑新增共用等）
//             var value = el.value                              //输入框的初始值
//             var group = el.getAttribute('group') || 'base'    //分组，一个表单框在多个组呢？这个还没设，要兼容。 通过类似 'group1 group2 group3 group4'
//             var tag = el.getAttribute('tag')
//             var regMsg = el.getAttribute('regMsg') || ''   //针对正则的自定义报错
//             var baseRule = []                              //默认的校验规则             --不用写，默认存在的规则（如非空），优先级最高
//             var customRule = []                            //用户自定义的规则（组件中） --bingding.value
//             var optionalRule = []                          //配置项中引申出来的规则，优先级最低

//             assert(tag, '未设置输入框的tag')
//             assert(vm.va, '实例的data选项上，未设置va对象')  //实例上如果没有设置结果则报错。
//             assert(field, '未设置输入框字段')
//             var va = createVa(vm, field)  //单例模式创建va，绑定在vm上
//             va.fieldOrder.push(field)     //字段的检验顺序
//             va.group[group].push(field)   //分组
//             var NonEmpty = new Rule('NonEmpty', true, '')
//             //默认非空
//             if (option.CanNull === undefined) {
//                 baseRule.push(NonEmpty)
//             }

//             //如果regList里有name对应的，直接就加进optionalConfig
//             if (regList[field]) {
//                 optionalRule.push(new Rule('reg', regList[field], regMsg))
//             }

//             //如果modefiers中的字段有在正则表里，将其加入optionalRule
//             var regOptions = Object.keys(option);
//             for (var i = 0; i < regOptions.length; i++) {
//                 var regOption = regOptions[i]
//                 if (regList[regOptions[i]]) {
//                     optionalRule.push(new Rule('reg', regList[regOption], regMsg))
//                 }
//             }

//             //用户自定义的规则
//             if (binding.value !== undefined) {
//                 customRule = binding.value.map(item => {
//                     var ruleType = Object.keys(item)[0];
//                     var errMsg = ruleType === 'reg' ? regMsg : ''
//                     return new Rule(ruleType, item[ruleType], errMsg)
//                 })
//             }

//             var finalRules = mergeRule(baseRule, optionalRule, customRule)
//             var hasUniqueRule = false
//             //对联合校验的进行预处理
//             finalRules.forEach(rule => {
//                 var { ruleType, ruleValue } = rule
//                 if (ruleType === 'equal') {
//                     if (va.equalGroup[ruleValue] === undefined) {
//                         va.equalGroup[ruleValue] = [field]
//                     } else {
//                         va.equalGroup[ruleValue].push(field)
//                     }
//                 }

//                 if (ruleType === 'unique') {
//                     hasUniqueRule = ruleValue
//                     if (va.uniqueGroup[ruleValue] === undefined) {
//                         va.uniqueGroup[ruleValue] = [field]
//                     } else {
//                         va.uniqueGroup[ruleValue].push(field)
//                     }
//                 }
//             })

//             var wvForm = new WvForm(el, finalRules, option)
//             va.forms[field] = wvForm

//             if (checkWhenChange) {
//                 function validateSingle() {
//                     va.refreshValue(field, el.value)  //更新值
//                     //如果允许为空的此时为空，不校验
//                     if (wvForm.value === '' && option.CanNull) {
//                         va.vmResult[field] = {}   //如果为空，把界面显示上面的提示清掉
//                         return
//                     }

//                     if (wvForm.noCheck === false) {
//                         va.setVmResult(field)
//                     }

//                     var isEqualTarget = false
//                     for (var index in va.equalGroup) {
//                         if (index === field) {
//                             isEqualTarget = true
//                         }
//                     }

//                     //相等框的联合校验
//                     if (isEqualTarget) {
//                         va.equalGroup[field].forEach(item => { va.setVmResult(item) })
//                     }

//                     //不同框的联合校验
//                     if (hasUniqueRule) {
//                         va.uniqueGroup[hasUniqueRule].forEach(item => { va.setVmResult(item) })
//                     }
//                 }

//                 //在change和blur上都绑定了处理事件
//                 el.addEventListener('change', validateSingle)
//                 el.addEventListener('blur', validateSingle)
//             }

//         },
//     })
// }
